package com.ruoyi.swla2.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.common.constant.UrlConstants;
import com.ruoyi.common.core.domain.ResponseEntity;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.swla2.bo.TerminalBo;
import com.ruoyi.swla2.bo.TerminalHistoryDataBo;
import com.ruoyi.swla2.domain.RealtimeGatherData;
import com.ruoyi.swla2.domain.TerminalHistoryData;
import com.ruoyi.swla2.domain.Terminals;
import com.ruoyi.swla2.mapper.RealtimeGatherDataMapper;
import com.ruoyi.swla2.mapper.TerminalHistoryDataMapper;
import com.ruoyi.swla2.mapper.TerminalsMapper;
import com.ruoyi.swla2.model.ZoneJoinModel;
import com.ruoyi.swla2.service.ITerminalHistoryDataService;
import com.ruoyi.swla2.service.ITerminalsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 大表档案Service业务层处理
 *
 * @author gdqt
 * @date 2023-06-16
 */
@Slf4j
@Service
public class TerminalsServiceImpl implements ITerminalsService, UrlConstants {
    @Autowired
    private TerminalsMapper terminalsMapper;

    @Autowired
    private RealtimeGatherDataMapper realtimeGatherDataMapper;

    @Autowired
    private ITerminalHistoryDataService terminalHistoryDataService;

    @Value("${interface.biaowu.data-api}")
    public String bwApi;

    /**
     * 查询大表档案
     *
     * @param ID 大表档案主键
     * @return 大表档案
     */
    @Override
    public Terminals selectTerminalsByID(Long ID) {
        return terminalsMapper.selectTerminalsByID(ID);
    }

    /**
     * 查询大表档案列表
     *
     * @param terminals 大表档案
     * @return 大表档案
     */
    @Override
    public List<Terminals> selectTerminalsList(Terminals terminals) {
        return terminalsMapper.selectTerminalsList(terminals);
    }

    /**
     * 新增大表档案
     *
     * @param terminals 大表档案
     * @return 结果
     */
    @Override
    public int insertTerminals(Terminals terminals) {
        return terminalsMapper.insertTerminals(terminals);
    }

    /**
     * 修改大表档案
     *
     * @param terminals 大表档案
     * @return 结果
     */
    @Override
    public int updateTerminals(Terminals terminals) {
        return terminalsMapper.updateTerminals(terminals);
    }

    /**
     * 批量删除大表档案
     *
     * @param IDs 需要删除的大表档案主键
     * @return 结果
     */
    @Override
    public int deleteTerminalsByIDs(Long[] IDs) {
        return terminalsMapper.deleteTerminalsByIDs(IDs);
    }

    /**
     * 删除大表档案信息
     *
     * @param ID 大表档案主键
     * @return 结果
     */
    @Override
    public int deleteTerminalsByID(Long ID) {
        return terminalsMapper.deleteTerminalsByID(ID);
    }

    @Override
    public List<Terminals> getUnbindTerminals(ZoneJoinModel model) {
        return terminalsMapper.getUnbindTerminals(model);
    }

    @Override
    public Terminals selectTerminalsByTerminalId(String terminalId) {
        return terminalsMapper.selectTerminalsByTerminalId(terminalId);
    }

    @Override
    public void syncDb(Date maxTime) {
        String terminalUrl= bwApi + TERMINAL_API;

        //查找漏损系统中老数据
        List<Terminals> oldList = terminalsMapper.selectList(new LambdaQueryWrapper<>());
        Map<String,Terminals> terminalIdOldMap = oldList.stream().collect(Collectors.toMap(Terminals::getTerminalID, Function.identity()));
        //查找历史数据
//        List<TerminalHistoryData> oldHistoryList = terminalsMapper.selectMaxReadDateWithTerminal("000000");
//        Map<String,TerminalHistoryData> maxReadDateMap = oldHistoryList.stream().collect(Collectors.toMap(TerminalHistoryData::getTerminalID, Function.identity()));

        ResponseEntity<TerminalBo> responseEntity = getUrlData(terminalUrl,"1");
        List<TerminalBo> terminalsDbs = responseEntity.getRows();
        long total = responseEntity.getTotal();
        //总页数
        int maxPageNum = (int) Math.ceil((double) total / DT_PAGE_SIZE);
        log.info("maxPageNum={}",maxPageNum);
        for (int pageNum = 1; pageNum <= maxPageNum; pageNum++) {
            if (pageNum > 1) {
                ResponseEntity<TerminalBo> tempEntity = getUrlData(terminalUrl,String.valueOf(pageNum));
                terminalsDbs = tempEntity.getRows();
            }
            if (CollectionUtils.isEmpty(terminalsDbs)) {
                log.info("url：{}无大表信息数据", terminalUrl);
                continue;
            }
            // 户表信息
            for (TerminalBo terminalsDb : terminalsDbs) {
                String terminalId = terminalsDb.getDeviceUserNo();
                if (StringUtils.isEmpty(terminalId)) {
                    log.info("设备【{}】terminalId为空", terminalsDb);
                    continue;
                }
                Long caliber = null;
                Long locationNb = terminalsDb.getLocationNb();
                if(terminalsDb.getCaliber() != null && !terminalsDb.getCaliber().isEmpty()) {
                    caliber =  Long.parseLong(terminalsDb.getCaliber().replace("DN","").replace("mm",""));
                }
                Long supplierId = terminalsDb.getSupplierId();
                //不包含，则需要新增到漏损控制系统中
                //1.档案数据
                if(!terminalIdOldMap.containsKey(terminalId)){
                    Terminals terminals = new Terminals();
                    terminals.setTenantId("000000");
                    terminals.setSupplierID(String.valueOf(supplierId));
                    terminals.setTerminalID(terminalId);
                    terminals.setTerminalName(terminalsDb.getDeviceName());
                    terminals.setTerminalMark(1L);
                    terminals.setCurrentPressure(terminalsDb.getPressureDisplay() != null ? Long.parseLong(terminalsDb.getPressureDisplay()) : 0L);
                    terminals.setTerminalInstallAddr(terminalsDb.getInstallAddr());
                    terminals.setTerminalInstallDate(terminalsDb.getInstallDate());
                    terminals.setCaliber(caliber);
                    terminals.setCollectionFrequency(terminalsDb.getReadingFrequency());
                    terminals.setUploadFrequency(terminalsDb.getUpFrequency());
                    terminals.setUseType(2L);
                    terminals.setCreateDatetime(new Date());
                    terminals.setIMEI(terminalsDb.getImei());
                    terminals.setEasIonId(terminalsDb.getDeviceNo());
                    try{
                        terminalsMapper.insert(terminals);
                    }catch (Exception e) {
                        log.error("保存大表{}档案数据失败，失败原因：{}",terminalId,e.getMessage());
                    }
                }
                //2.实时数据
                try{
                    if(terminalsDb.getCollectTime()!=null){
                        //删除实时数据
                        realtimeGatherDataMapper.delete(new LambdaQueryWrapper<RealtimeGatherData>().eq(RealtimeGatherData::getTenantId,"000000")
                                .eq(RealtimeGatherData::getTerminalID,terminalId));
                        //更新实时数据
                        RealtimeGatherData realtimeGatherData = new RealtimeGatherData();
                        realtimeGatherData.setTenantId("000000");
                        realtimeGatherData.setTerminalID(terminalId);
                        realtimeGatherData.setEasIonId(terminalsDb.getDeviceNo());
                        realtimeGatherData.setCaliber(caliber);
                        realtimeGatherData.setTotalFlow(terminalsDb.getReadNumber());
                        realtimeGatherData.setReadNumber(terminalsDb.getForwardNumber());
                        realtimeGatherData.setReverseNumber(terminalsDb.getReverseNumber());
                        realtimeGatherData.setInstantNumber(terminalsDb.getInstantNumber());
                        realtimeGatherData.setInstantVelocity(terminalsDb.getInstantVelocity());
                        realtimeGatherData.setPressure(terminalsDb.getPressure());
                        realtimeGatherData.setTerminalVol(terminalsDb.getBatteryVoltage());
                        realtimeGatherData.setTerminalCSQ(terminalsDb.getTerminalCsq());
                        realtimeGatherData.setValveState(!StringUtils.isEmpty(terminalsDb.getValveStatus()) ? Long.parseLong(terminalsDb.getValveStatus()) : 0L);
                        realtimeGatherData.setWarnFlag(0);
//                        realtimeGatherData.setReadDate(terminalsDb.getCollectTime());
                        realtimeGatherData.setReadDate(terminalsDb.getCollectTime());
                        realtimeGatherData.setType(1);
                        realtimeGatherData.setFrequency(terminalsDb.getReadingFrequency()!=null ? String.valueOf(terminalsDb.getReadingFrequency()) : null);
                        realtimeGatherDataMapper.insert(realtimeGatherData);
                    }
                } catch (Exception e) {
                    log.error("保存大表{}实时数据失败，失败原因：{}",terminalId,e.getMessage());
                }

                //同步历史数据
                if(locationNb != null){
                    syncHistoryData(terminalId,locationNb,supplierId,terminalsDb.getDeviceNo(),maxTime,null);
                }
            }
        }
    }

    private void syncHistoryData(String terminalId,Long locationNb,Long supplierId,String deviceNo,Date maxTime,Map<String,TerminalHistoryData> maxReadDateMap){
        String terminalHistoryUrl= bwApi + TERMINAL_HISTORY_API;
        try{
            String collectTimeBegin = maxTime==null ? DateUtil.formatDateTime(DateUtil.offsetDay(new Date(),-1)) : DateUtil.formatDateTime(maxTime);
//            if(maxReadDateMap.containsKey(terminalId)){
//                collectTimeBegin = DateUtil.formatDateTime(DateUtil.offsetMinute(maxReadDateMap.get(terminalId).getReadDate(),1));
//            }
            //更新历史数据
            Map<String, Object> historyParams = new HashMap<>();
            historyParams.put(PARMA_NAME_LOCATION_NB,locationNb);
            historyParams.put("collectTimeBegin",collectTimeBegin);//采集开始时间
            historyParams.put("collectTimeEnd", DateUtil.now());//采集结束时间
            historyParams.put(PARMA_NAME_PAGE_NUM,1);
            historyParams.put(PARMA_NAME_PAGE_SIZE,DT_PAGE_SIZE);
            String historyResult = HttpUtils.sendGet(terminalHistoryUrl, HttpUtil.toParams(historyParams));
            ResponseEntity<TerminalHistoryDataBo> historyEntity = JSONObject.parseObject(historyResult, new TypeReference<ResponseEntity<TerminalHistoryDataBo>>() {});
            List<TerminalHistoryDataBo> historyDataBos = historyEntity.getRows();
            //总页数
            int maxPageNum = (int) Math.ceil((double) historyEntity.getTotal() / DT_PAGE_SIZE);
            for (int pageNum = 1; pageNum <= maxPageNum; pageNum++) {
                List<TerminalHistoryData> insertHistoryList = new ArrayList<>();
                if (pageNum > 1) {
                    historyParams.put(PARMA_NAME_PAGE_NUM, String.valueOf(pageNum));
                    historyResult = HttpUtils.sendGet(terminalHistoryUrl, HttpUtil.toParams(historyParams));
                    ResponseEntity<TerminalHistoryDataBo> tempEntity = JSONObject.parseObject(historyResult, new TypeReference<ResponseEntity<TerminalHistoryDataBo>>() {
                    });
                    historyDataBos = tempEntity.getRows();
                }
                if (CollectionUtils.isEmpty(historyDataBos)) {
                    log.info("url：{}无大表历史数据", terminalHistoryUrl);
                    continue;
                }
                // 户表信息
                for (TerminalHistoryDataBo historyDataBo : historyDataBos) {
                    if(historyDataBo.getCollectTime() != null) {
                        TerminalHistoryData terminalHistoryData = new TerminalHistoryData();
                        terminalHistoryData.setEasIonId(deviceNo);
                        terminalHistoryData.setTerminalID(terminalId);
                        terminalHistoryData.setSupplierID(supplierId);
                        terminalHistoryData.setTenantId("000000");
                        terminalHistoryData.setTotalFlow(historyDataBo.getReadNumber());
                        terminalHistoryData.setReadNumber(historyDataBo.getForwardNumber());
                        terminalHistoryData.setReverseNumber(historyDataBo.getReverseNumber());
                        terminalHistoryData.setTerminalVol(historyDataBo.getBatteryVoltage());
                        terminalHistoryData.setInstantNumber(historyDataBo.getInstantNumber());
                        terminalHistoryData.setInstantVelocity(historyDataBo.getInstantVelocity());
                        terminalHistoryData.setPressure(historyDataBo.getPressure());
                        terminalHistoryData.setTerminalCSQ(historyDataBo.getTerminalCsq());
                        terminalHistoryData.setValveState(!StringUtils.isEmpty(historyDataBo.getValveStatus()) ? Long.parseLong(historyDataBo.getValveStatus()) : 0L);
                        terminalHistoryData.setWarnFlag(0);
                        terminalHistoryData.setReadDate(historyDataBo.getCollectTime());
                        terminalHistoryData.setCreateDate(new Date());
                        insertHistoryList.add(terminalHistoryData);
                    }
                }
                if(!insertHistoryList.isEmpty()){
                    terminalHistoryDataService.saveBatch(insertHistoryList);
                }
            }
        }catch (Exception e){
            log.error("保存大表{}历史数据失败，失败原因：{}",terminalId,e.getMessage());
        }
    }

    public ResponseEntity<TerminalBo> getUrlData(String terminalUrl,String pageNum){
        ResponseEntity<TerminalBo> res = new ResponseEntity<>();
        try{
            Map<String, Object> params = new HashMap<>();
            params.put(PARMA_NAME_PAGE_NUM,pageNum);
            params.put(PARMA_NAME_PAGE_SIZE,DT_PAGE_SIZE);
            String result = HttpUtils.sendGet(terminalUrl, HttpUtil.toParams(params));
//            res = JSONObject.parseObject(result, new TypeReference<ResponseEntity<TerminalBo>>() {}, JSONReader.Feature.SupportAutoType);
            JSONObject jsonObject = JSON.parseObject(result);
            List<TerminalBo> rows = jsonObject.getList("rows",TerminalBo.class);
            long total = jsonObject.getLong("total");
            res.setRows(rows);
            res.setTotal(total);
        } catch (Exception e) {
            log.error("从接口：{}获取数据时出错", terminalUrl);
            log.error("报错原因：{}", e.getMessage());
            res.setRows(new ArrayList<>());
            res.setTotal(0);
        }
        return res;
    }
}
